<template>
  <div>
    <el-container>
      <el-aside width="400px">
        <div>
          <el-button @click="openCamera" style="margin-top: 20px">打开摄像头</el-button>
          <el-button type="success" @click="takePhoto" style="margin-top: 20px">拍照识别</el-button>
          <video ref="video" width="320" height="240"></video>
          <canvas ref="canvas" width="320" height="240" style="display: none;"></canvas>
          <!--    <img :src="photoDataUrl" alt="拍照的图片">-->
        </div>

        <el-divider></el-divider>
        请输入信息查询匹配查询相关医院
        <div style="margin-top: 15px;">
          <el-col :span="12" style="width: 25%">
            <el-autocomplete
                class="inline-input"
                v-model="state0"
                :fetch-suggestions="querySearch"
                placeholder="省"
            ></el-autocomplete>
          </el-col>

          <el-col :span="12" style="width: 25%">
            <el-autocomplete
                class="inline-input"
                v-model="state1"
                :fetch-suggestions="querySearch1"
                placeholder="市"
            ></el-autocomplete>
          </el-col>

          <el-col :span="12" style="width: 30%">
            <el-autocomplete
                class="inline-input"
                v-model="state2"
                :fetch-suggestions="querySearch2"
                placeholder="科室"
            ></el-autocomplete>
          </el-col>
          <el-button type="success" icon="el-icon-check" @click="charFormsg"
                     style="margin-left: 10px;margin-bottom: 20px"></el-button>
        </div>

      </el-aside>
      <el-container>
        <el-header class="styled-header">
          <el-menu mode="horizontal" router="router">
            <el-menu-item index="/drug">药品检索</el-menu-item>
            <el-menu-item index="/case">病例说明</el-menu-item>
            <el-menu-item index="/symptom">症状查询</el-menu-item>
            <el-menu-item index="/place">医院信息查找</el-menu-item>
            <el-button type="text">？使用说明</el-button>
          </el-menu>
        </el-header>
        <el-main
            class="card-container"
            style="display: flex; flex-direction: row; align-items: center; height: 580px; max-width: 100%; justify-content: space-between;">

          <el-card shadow="hover" style="width: calc(50% - 5px);">
            <el-descriptions class="margin-top" :column="3">
              <el-descriptions-item label="医院介绍">
                <div v-html="messages"></div>
              </el-descriptions-item>
            </el-descriptions>
            <el-button type="success" @click="speakTtsSpeech">语音播报</el-button>
          </el-card>
          <el-card  style="flex: 1;margin-left: 20px">
            <div>
              <el-card style="margin-bottom: 8px">
                <div>
                <span>医院名称：</span> {{hospital}}
                </div>
                <div>
                  <span>简介：</span> {{intro}}
                </div>
                <div>
                  <span>地址：</span> {{addr}}
                </div>
              </el-card >
              <el-card style="margin-bottom: 8px">
                <div>
                  <span>医院名称：</span> {{hospital1}}
                </div>
                <div>
                  <span>简介：</span> {{intro1}}
                </div>
                <div>
                  <span>地址：</span> {{addr1}}
                </div>
              </el-card>
            </div>

          </el-card>
        </el-main>

      </el-container>
    </el-container>
    <el-dialog
        title="提示"
        :visible.sync="centerDialogVisible"
        width="70%"
        center>
      <div style="display: flex;">
        <span><img src="@/assets/helpme1.png" style="width: 80%; height: auto;" alt=""/></span>
        <span><img src="@/assets/helpme2.png" style="width: 80%; height: 80%;" alt=""/></span>
      </div>
      <span slot="footer" class="dialog-footer">
      <el-button type="primary" @click="centerDialogVisible = false">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
import request from "@/utils/request";
import Speech from 'speak-tts'

export default {

  data() {
    return {
      //图片上传功能
      imgUrl: '',
      dialogImageUrl: '',
      dialogVisible: false,
      doName: '',
      //主显示内容
      messages: '',
      speech: '',
      //使用说明
      centerDialogVisible: false,
      //拍的照片存储的容器
      photoDataUrl: '',
      stream: null,
      videoElement: null,
      canvasElement: null,
      //提示输入
      restaurants: [],
      restaurants1: [],
      restaurants2: [],
      state0: '',
      state1: '',
      state2: '',
      hospital: '',
      hospital1: '',
      intro:'',
      intro1:'',
      addr:'',
      addr1:''
    };
  },
  methods: {
    // 播报系统js
    //初始化播报系统
    speechInit() {
      this.speech = new Speech();
      this.speech.setLanguage("zh-CN");
      this.speech.init().then(() => {
      });
    },
    //为按钮添加了点击播报事件
    speakTtsSpeech() {
      this.speech.speak({text: this.desc}).then(() => {
      });
    },

    //摄像头上传拍照
    openCamera() {
      navigator.mediaDevices.getUserMedia({video: true})
          .then((stream) => {
            //将视频流赋值给 Vue 实例的 stream 属性
            this.stream = stream;
            //视频流绑定到 HTML5 的 video 元素上，使用 srcObject 属性来实现，并调用 play 方法播放视频
            this.videoElement.srcObject = stream;
            this.videoElement.play();
            //通过以上的这样的操作，即可实现摄像头视频流的捕获和展示。
          })
          .catch((error) => {
            console.error('打开摄像头失败：', error);
          });
    },
    takePhoto() {
      // 获取 Canvas 元素的上下文对象
      const context = this.canvasElement.getContext('2d');

      // 将视频元素中当前帧的图像绘制到 Canvas 中
      context.drawImage(this.videoElement, 0, 0, this.canvasElement.width, this.canvasElement.height);

      // 将 Canvas 中的图像转换为 Blob 对象
      this.canvasElement.toBlob((blob) => {
        // 创建一个 File 对象
        const file = new File([blob], 'photo.jpg', {type: 'image/jpeg'});

        // 调用 getTracks() 方法遍历摄像头视频流的所有轨道，并逐一停止它们，这样就关闭了摄像头
        this.stream.getTracks().forEach((track) => {
          track.stop();
        });

        // 发送文件给后台
        this.uploadPhoto(file);
      }, 'image/jpeg');
    },

    async uploadPhoto(file) {
      const formData = new FormData();
      formData.append('file', file);
      var _this = this
      _this.messages=""
      const response = await fetch('http://localhost:8088/ai/hospitalSearch', {
        method: 'POST',
        body:formData
      });
      if (response.ok) {
        const reader = response.body.getReader();
        const stream = new ReadableStream({
          async start(controller) {
            function fetchData() {
              reader.read().then(({done, value}) => {
                if (done) {
                  controller.close();
                  return;
                }
                const chunkText = new TextDecoder().decode(value);
                async function processChunkText(chunkText) {
                  try {
                    const dataArray = JSON.parse(chunkText);
                    for (const data of dataArray) {
                      if (data.end === true) {
                        return;
                      }
                      if (data.result) {
                        const text = data.result;
                        // 假设 _this 是当前上下文的引用，确保它在函数外部已经定义
                        _this.messages += text;
                        // 休眠一秒钟
                        await new Promise(resolve => setTimeout(resolve, 1000));
                      }
                    }
                  } catch (error) {
                    // 处理 JSON.parse 可能出现的错误
                    console.error('Error parsing JSON:', error);
                  }
                }
                processChunkText(chunkText)
                fetchData();
              });
            }
            fetchData();
          }
        });
        console.log(_this.messages)
        await new Response(stream).text();
      } else {
        this.$message.error('发生错误')
      }
    },
    charFormsg() {
      request.post('/ask/top2', {
        "province": this.state0,
        "city": this.state1,
        "department": this.state2
      }).then((res) => {
        this.hospital = res.data[0].name
        this.hospital1 = res.data[1].name
        this.intro=res.data[0].intro
        this.intro1=res.data[1].intro
        this.addr=res.data[0].addr
        this.addr1=res.data[1].addr
      }).catch((error) => {
        console.error('照片上传失败：', error);
      });
    },
    querySearch(queryString, cb) {
      var restaurants = this.restaurants;
      var results = queryString ? restaurants.filter(this.createFilter(queryString)) : restaurants;
      // 调用 callback 返回建议列表的数据
      cb(results);
    },
    querySearch1(queryString, cb) {
      var restaurants1 = this.restaurants1;
      var results = queryString ? restaurants1.filter(this.createFilter(queryString)) : restaurants1;
      // 调用 callback 返回建议列表的数据
      cb(results);
    }, querySearch2(queryString, cb) {
      var restaurants2 = this.restaurants2;
      var results = queryString ? restaurants2.filter(this.createFilter(queryString)) : restaurants2;
      // 调用 callback 返回建议列表的数据
      cb(results);
    },

    createFilter(queryString) {
      return (restaurant) => {
        return (restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0);
      };
    },
    loadAll() {
      return [
        {"value": "河北省"},
        {"value": "河南省"},
        {"value": "山西省"},
        {"value": "山东省"},
        {"value": "四川省"},
        {"value": "广西省"},
        {"value": "广东省"},
      ];
    },
    loadAll1() {
      return [
        {"value": "石家庄"},
        {"value": "唐山"},
        {"value": "秦皇岛"},
        {"value": "邯郸"},
        {"value": "邢台"},
        {"value": "保定"},
        {"value": "张家口"},
        {"value": "承德"},
        {"value": "沧州"},
        {"value": "廊坊"},
        {"value": "衡水"},
      ];
    },
    loadAll2() {
      return [
        {"value": "内科"},
        {"value": "外科"},
        {"value": "妇产科"},
        {"value": "儿科"},
        {"value": "五官科"},
      ];
    },
  },
  mounted() {
    this.restaurants = this.loadAll();
    this.restaurants1 = this.loadAll1();
    this.restaurants2 = this.loadAll2();

    this.speechInit();
    //通过 ref 获取到的 video 元素赋值给组件实例的 videoElement 属性
    this.videoElement = this.$refs.video;
    //通过 ref 获取到的 canvas 元素赋值给组件实例的 canvasElement 属性
    this.canvasElement = this.$refs.canvas;
  }
}
</script>

<style>
.styled-header {
  font-size: 24px; /* 设置字体大小 */
  font-weight: bold; /* 设置字体加粗 */
  color: #333; /* 设置字体颜色 */
  text-align: center; /* 设置文本居中 */
  padding: 20px 0; /* 设置上下内边距 */
  border-bottom: 2px solid #ccc; /* 添加底部边框 */
  background-color: #f0f0f0; /* 设置背景颜色 */
}

.el-header {

  background-color: #cedaf8;
  text-align: center;
}

.el-aside {
  background-color: #E9EEF3;
  color: #333;
  text-align: center;
}

.el-main {
  background-color: #f0f0f0;
  color: #333;
  text-align: center;

}

.text {
  font-size: 14px;
}

.item {
  padding: 18px 0;
}


.box-card1 {
  width: 968px;
  margin-top: 10px;
}

.card-container {
  /* 下面这些样式是为了让子元素按行排列并且居中对齐，可根据实际需求调整 */
  display: flex;
  flex-wrap: nowrap;
  justify-content: space-between;
}
</style>